package top.ljlgithub.api.service.impl;

import org.apache.ibatis.reflection.ArrayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import top.ljlgithub.api.bean.Role;
import top.ljlgithub.api.bean.TreeBO;
import top.ljlgithub.api.bean.TreeRole;
import top.ljlgithub.api.mapper.RightMapper;
import top.ljlgithub.api.mapper.RoleMapper;
import top.ljlgithub.api.service.RightService;
import top.ljlgithub.api.service.RoleService;
import top.ljlgithub.api.utils.RedisUtil;

import java.io.*;
import java.sql.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @ClassName
 * @Description TODO
 * @Author L1470
 * @Date 2021/5/6 18:31
 * @Version 1.0
 **/
@Service
public class RoleServiceImpl implements RoleService {
    private final String KEY = "top.ljlgithub.api.shiro.realm.JwtRealm.authorizationCache";

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    RightService rightService;

    @Override
    public List<TreeRole> getTreeRole() {
        List<TreeRole> treeRole = roleMapper.getTreeRole();
        List<TreeBO> treeBOS = rightService.selectNodeTreeByPid();
        List<String> ids = roleMapper.getIds();
        for (int i = 0; i < treeRole.size(); i++) {
            //List<TreeBO> treeBOS1 = new ArrayList<>(treeBOS);
            List<TreeBO> treeBOS1 = depCopy(treeBOS);
            setChildren(treeBOS1, ids.get(i));
            treeRole.get(i).setChildren(treeBOS1);
        }
        return treeRole;
    }

    @Override
    public Role addRole(Role role) {
        roleMapper.addRole(role);
        return role;
    }

    @Override
    public Role findRole(int id) {
        Role role = roleMapper.findRoleById(id);
        return role;
    }

    @Override
    public Role updateRole(Role role) {
        roleMapper.updateRole(role);
        role = roleMapper.findRoleById(role.getRoleId());
        return role;
    }

    @Override
    public void deleteRole(int id) {
        roleMapper.deleteRoleById(id);
    }

    @Override
    public List<TreeBO> updateRight(String ids, int id) {
        roleMapper.updateRight(ids, id);
        List<TreeBO> treeBOS = rightService.selectNodeTreeByPid();
        setChildren(treeBOS, ids);
        List<String> users = roleMapper.findUsernameById(id);
        for (String user : users) {
            redisUtil.hdel(KEY, user);
        }
        return treeBOS;

    }

    @Override
    public String findIdsById(int id) {
        String ids = roleMapper.findIdsById(id);
        return ids;
    }

    private void setChildren(List<TreeBO> treeBOS, String ids) {
        if (treeBOS != null && treeBOS.size() != 0) {
            for (int i = 0; i < treeBOS.size(); i++) {
                if (!ids.contains(treeBOS.get(i).getId())) {
                    treeBOS.remove(i);
                    i--;
                } else {
                    setChildren(treeBOS.get(i).getChildren(), ids);
                }
            }
        }
    }

    private static <T> List<T> depCopy(List<T> srcList) {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        try {
            ObjectOutputStream out = new ObjectOutputStream(byteOut);
            out.writeObject(srcList);

            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream inStream = new ObjectInputStream(byteIn);
            List<T> destList = (List<T>) inStream.readObject();
            return destList;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

}
